package com.ncloud.billing.service.impl;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSONObject;
import com.ncloud.billing.common.DateUtil;
import com.ncloud.billing.entity.Bill;
import com.ncloud.billing.entity.BsAccount;
import com.ncloud.billing.entity.BsContract;
import com.ncloud.billing.entity.BsCust;
import com.ncloud.billing.entity.BsCycle;
import com.ncloud.billing.entity.BsDiscnt;
import com.ncloud.billing.entity.BsDiscntFee;
import com.ncloud.billing.entity.BsNode;
import com.ncloud.billing.entity.BsNodeItem;
import com.ncloud.billing.entity.BsProduct;
import com.ncloud.billing.entity.BsProject;
import com.ncloud.billing.mapper.BillMapper;
import com.ncloud.billing.mapper.BsAccountMapper;
import com.ncloud.billing.mapper.BsAttrMapper;
import com.ncloud.billing.mapper.BsContractMapper;
import com.ncloud.billing.mapper.BsCustMapper;
import com.ncloud.billing.mapper.BsCycleMapper;
import com.ncloud.billing.mapper.BsDiscntFeeMapper;
import com.ncloud.billing.mapper.BsDiscntMapper;
import com.ncloud.billing.mapper.BsNodeItemMapper;
import com.ncloud.billing.mapper.BsNodeMapper;
import com.ncloud.billing.mapper.BsProductMapper;
import com.ncloud.billing.mapper.BsProjectMapper;
import com.ncloud.param.service.SequenceService;

@Service
public class GenBillTransServiceImpl{
	private static final Logger logger = LogManager.getLogger(GenBillTransServiceImpl.class);
	@Resource
	private BsCustMapper bsCustMapper;
	@Resource
	private BsAccountMapper bsAccountMapper;
	@Resource
	private BsContractMapper bsContractMapper;
	@Resource
	private BsNodeItemMapper bsNodeItemMapper;
	@Resource
	private BsNodeMapper bsNodeMapper;
	@Resource
	private BsProjectMapper bsProjectMapper;
	@Resource
	private BsProductMapper bsProductMapper;
	@Resource
	private BsDiscntMapper bsDiscntMapper;
	@Resource
	private BsDiscntFeeMapper bsDiscntFeeMapper;
	@Resource
	private BsAttrMapper bsAttrMapper;
	@Resource
	private BillMapper billMapper;
	@Resource
	private BsCycleMapper bsCycleMapper;
	@Reference
	private SequenceService sequenceService;
	//@Transactional(propagation=Propagation.REQUIRED)
	public JSONObject genCustBill(JSONObject json) throws ParseException {
		//当前账期
		List<BsCycle> currentCycle = bsCycleMapper.getCurrentCycle();
		if (currentCycle.size()==0){return json;}
		Integer current_cycle_id=currentCycle.get(0).getCycle_id();
		//未出账账单账期
		List<BsCycle> minBillCycle = bsCycleMapper.getMinBillCycle();
		if (minBillCycle.size()==0){return json;}
		Integer bill_cycle_id=minBillCycle.get(0).getCycle_id();
		/*if(json.containsKey("bill_cycle_id")){
			bill_cycle_id = json.getInteger("bill_cycle_id");
		}*/
		String custIDs="";
		if(json.containsKey("cust_ids")){
			custIDs = json.getString("cust_ids");
		}
		//出账月月初时间和月末时间
		Date billDeginDate=minBillCycle.get(0).getBegin_time();
		Date billEndDate=minBillCycle.get(0).getEnd_time();
		Integer currentMonthDays=DateUtil.daysBetween(billDeginDate, billEndDate)+1;
		SimpleDateFormat systemdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
		//String sysdate = systemdf.format(new Date());
		List<BsCust> bsCusts=new ArrayList<BsCust>();
		if("".equals(custIDs)){
			bsCusts=bsCustMapper.getBsCustAll();
		}else{
			bsCusts=bsCustMapper.getBsCustByCustID(custIDs);
		}
		for(int custIndex=0;custIndex<bsCusts.size();custIndex++){
			BsCust bsCust = bsCusts.get(custIndex);
			Long cust_id = bsCust.getCustId();
			Long acct_id = 0l;
			//客户对应账户信息
			List<BsAccount> bsAccounts=bsAccountMapper.getBsAccountByCustID(cust_id);
			if(bsAccounts!=null && bsAccounts.size()>0){
				acct_id = bsAccounts.get(0).getAcctId();	
			}
			//========================================================================
			//客户对应产品信息
			List<BsProduct> bsProducts=bsProductMapper.getBsProductByCustID(cust_id);
			for(int productIndex=0;productIndex<bsProducts.size();productIndex++){
				BsProduct bsProduct = bsProducts.get(productIndex);
				Long prod_inst_id = bsProduct.getProd_inst_id();
				Long prod_id = bsProduct.getProd_id();
				String prod_name = bsProduct.getProd_name();
				//产品对应资费套餐信息
				List<BsDiscnt> bsDiscnts=bsDiscntMapper.getBsDiscntByProdInstID(prod_inst_id,billDeginDate,billEndDate);
				for(int discntIndex=0;discntIndex<bsDiscnts.size();discntIndex++){
					BsDiscnt bsDiscnt = bsDiscnts.get(discntIndex);
					Long discnt_inst_id = bsDiscnt.getDiscnt_inst_id();
					Long discnt_id = bsDiscnt.getDiscnt_id();
					String discnt_name = bsDiscnt.getDiscnt_name();
					//产品对应资费套餐信息
					//账单实体
					Bill bill = new Bill();
					//节点对应节点属性信息
					Integer timeLength=1; 
					Long payMoney=0l;
					Long monthPayMoney=0l;
					Long minFee=0l;
					Long monthMinFee=0l;
					Long maxFee=0l;
					Long monthMaxFee=0l;
					Long oldFeeValue=0l;
					//=======================================================================
					BsDiscntFee bsDiscntFee=new BsDiscntFee();
					List<BsDiscntFee> bsDiscntFees = bsDiscntFeeMapper.getBsDiscntFeeByDiscntInstID(cust_id,discnt_inst_id);
					if(bsDiscntFees!=null&&bsDiscntFees.size()>0){
						bsDiscntFee=bsDiscntFees.get(0);
						timeLength=bsDiscntFee.getBilling_cycle();
						payMoney=bsDiscntFee.getReceived_fee();
						minFee=bsDiscntFee.getBalance();
						maxFee=bsDiscntFee.getStandard();
						oldFeeValue=bsDiscntFee.getFee_value();
					}
					//=======================================================================
					if(payMoney==0){continue;}
					monthPayMoney=Math.round(payMoney*1.0/timeLength);
					monthMinFee=Math.round(minFee*1.0/timeLength);
					monthMaxFee=Math.round(maxFee*1.0/timeLength);
					
					//================================================
					Date nodeBeginDate = billDeginDate;
					Date nodeEndDate = billEndDate;
					//Integer useDays=currentMonthDays;//默认是账期一个月的天数
					if(bsDiscnt.getBegin_date().after(billDeginDate)){
						nodeBeginDate=bsDiscnt.getBegin_date();
					}
					if(bsDiscnt.getEnd_date().before(billEndDate)){
						nodeEndDate=bsDiscnt.getEnd_date();
					}
					Integer useDays=DateUtil.daysBetween(nodeBeginDate, nodeEndDate)+1;
					Long currentMonthPayMoney = Math.round(monthPayMoney*1.0*useDays/currentMonthDays);
					Long currentMonthMinFee = Math.round(monthMinFee*1.0*useDays/currentMonthDays);
					if(currentMonthPayMoney>payMoney-oldFeeValue){
						currentMonthPayMoney=payMoney-oldFeeValue;
					}
					bill.setFee(currentMonthPayMoney);
					bill.setBalance(currentMonthPayMoney);
					//bill.setAgent_fee(currentMonthMinFee);
					//bill.setAgent_balance(currentMonthMinFee);
					//================================================
					Long bill_id=sequenceService.getSequence("bill_id");
					bill.setBill_id(bill_id);
					bill.setCust_id(cust_id);
					bill.setAcct_id(acct_id);
					bill.setProd_inst_id(prod_inst_id);
					bill.setProd_id(prod_id);
					bill.setProd_name(prod_name);
					bill.setDiscnt_inst_id(discnt_inst_id);
					bill.setDiscnt_id(discnt_id);
					bill.setDiscnt_name(discnt_name);
					//bill.setProject_id(project_id);
					//bill.setContract_inst_id(contract_inst_id);
					//bill.setNode_id(node_id);
					bill.setCycle_id(bill_cycle_id);
					//bill.setItem_code(100000);
					bill.setLate_fee(0l);
					bill.setLate_balance(0l);
					//bill.setLatecal_time();
					bill.setBill_pay_tag("0");
					//bill.setAgent_bill_pay_tag("0");
					bill.setUpdate_time(new Date());
					bill.setUpdate_user_id(1l);
					bill.setRsrv_fee1(0l);
					bill.setRsrv_info1("");
					bill.setRemark("");
					billMapper.insertBill(bill);
					//修改bs_discnt_fee表fee_value的值 合计已经出账的金额
					bsDiscntFee.setFee_value(oldFeeValue+currentMonthPayMoney);
					bsDiscntFeeMapper.updateDiscntFeeValue(bsDiscntFee);
				}
			}
			//========================================================================
			logger.info("cust_id="+cust_id+" 账单生成结束");
		}
		if("".equals(custIDs)){
			BsCycle billCycle = new BsCycle();
			billCycle.setCycle_id(bill_cycle_id);
			billCycle.setAct_tag("1");
			BsCycle curCycle = new BsCycle();
			curCycle.setCycle_id(current_cycle_id);
			curCycle.setUse_tag("1");
			bsCycleMapper.updateCycleActTag(billCycle);
			bsCycleMapper.updateCycleUseTag(curCycle);
		}
		return json;
	}

	public JSONObject genBill(JSONObject json) throws ParseException {
		//默认获取上个月作为账单账期
		/*Calendar calendar=Calendar.getInstance();//获取当前日期 
		calendar.add(Calendar.MONTH,-1);
		SimpleDateFormat df = new SimpleDateFormat("yyyyMM");//设置日期格式
		String ex_month = df.format(calendar.getTime());*/
		//当前账期
		List<BsCycle> currentCycle = bsCycleMapper.getCurrentCycle();
		if (currentCycle.size()==0){return json;}
		Integer current_cycle_id=currentCycle.get(0).getCycle_id();
		//未出账账单账期
		List<BsCycle> minBillCycle = bsCycleMapper.getMinBillCycle();
		if (minBillCycle.size()==0){return json;}
		Integer bill_cycle_id=minBillCycle.get(0).getCycle_id();
		/*if(json.containsKey("bill_cycle_id")){
			bill_cycle_id = json.getInteger("bill_cycle_id");
		}*/
		String custIDs="";
		if(json.containsKey("cust_ids")){
			custIDs = json.getString("cust_ids");
		}
		//出账月月初时间和月末时间
		Date billDeginDate=minBillCycle.get(0).getBegin_time();
		Date billEndDate=minBillCycle.get(0).getEnd_time();
		Integer currentMonthDays=DateUtil.daysBetween(billDeginDate, billEndDate)+1;
		SimpleDateFormat systemdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
		//String sysdate = systemdf.format(new Date());
		List<BsCust> bsCusts=new ArrayList<BsCust>();
		if("".equals(custIDs)){
			bsCusts=bsCustMapper.getBsCustAll();
		}else{
			bsCusts=bsCustMapper.getBsCustByCustID(custIDs);
		}
		for(int custIndex=0;custIndex<bsCusts.size();custIndex++){
			BsCust bsCust = bsCusts.get(custIndex);
			Long cust_id = bsCust.getCustId();
			Long acct_id = 0l;
			//客户对应账户信息
			List<BsAccount> bsAccounts=bsAccountMapper.getBsAccountByCustID(cust_id);
			if(bsAccounts!=null && bsAccounts.size()>0){
				acct_id = bsAccounts.get(0).getAcctId();	
			}
			//客户对应项目信息
			List<BsProject> bsProjects=bsProjectMapper.getBsProjectByCustID(cust_id);
			for(int projectIndex=0;projectIndex<bsProjects.size();projectIndex++){
				BsProject bsProject = bsProjects.get(projectIndex);
				Long project_id = bsProject.getProjectId();
				//项目对应合同信息
				List<BsContract> bsContracts=bsContractMapper.getBsContractByProjectID(project_id);
				for(int contractIndex=0;contractIndex<bsContracts.size();contractIndex++){
					BsContract bsContract = bsContracts.get(contractIndex);
					String contract_id = bsContract.getContractId();
					Long contract_inst_id = bsContract.getContractInstId();
					//合同对应节点信息
					List<BsNode> bsNodes=bsNodeMapper.getBsNodeByContractInstID(contract_inst_id);
					for(int nodeIndex=0;nodeIndex<bsNodes.size();nodeIndex++){
						BsNode bsNode = bsNodes.get(nodeIndex);
						Long node_id = bsNode.getNodeId();
						if(bsNode.getEndDate().before(bsNode.getBeginDate())){
							continue;
						}
						//账单实体
						Bill bill = new Bill();
						//节点对应节点属性信息
						Integer timeLength=1; 
						Long payMoney=0l;
						Long monthPayMoney=0l;
						Long minFee=0l;
						Long monthMinFee=0l;
						Long maxFee=0l;
						Long monthMaxFee=0l;
						List<BsNodeItem> bsNodeItems=bsNodeItemMapper.getNodeItemByNodeID(node_id);
						for(int nodeAttrIndex=0;nodeAttrIndex<bsNodeItems.size();nodeAttrIndex++){
							BsNodeItem bsNodeItem = bsNodeItems.get(nodeAttrIndex);
							if("timeLength".equals(bsNodeItem.getAttrCode())){
								timeLength=Integer.valueOf(bsNodeItem.getAttrValue());
							}else if("payMoney".equals(bsNodeItem.getAttrCode())){
								payMoney=Long.valueOf(bsNodeItem.getAttrValue());
							}else if("minFee".equals(bsNodeItem.getAttrCode())){
								minFee=Long.valueOf(bsNodeItem.getAttrValue());
							}else if("maxFee".equals(bsNodeItem.getAttrCode())){
								maxFee=Long.valueOf(bsNodeItem.getAttrValue());
							}
						}
						if(payMoney==0){continue;}
						monthPayMoney=Math.round(payMoney*1.0/timeLength);
						monthMinFee=Math.round(minFee*1.0/timeLength);
						monthMaxFee=Math.round(maxFee*1.0/timeLength);
						
						//================================================
						Date nodeBeginDate = billDeginDate;
						Date nodeEndDate = billEndDate;
						//Integer useDays=currentMonthDays;//默认是账期一个月的天数
						if(bsNode.getBeginDate().after(billDeginDate)){
							nodeBeginDate=bsNode.getBeginDate();
						}
						if(bsNode.getEndDate().before(billEndDate)){
							nodeEndDate=bsNode.getEndDate();
						}
						Integer useDays=DateUtil.daysBetween(nodeBeginDate, nodeEndDate)+1;
						Long currentMonthPayMoney = Math.round(monthPayMoney*1.0*useDays/currentMonthDays);
						Long currentMonthMinFee = Math.round(monthMinFee*1.0*useDays/currentMonthDays);
						bill.setFee(currentMonthPayMoney);
						bill.setBalance(currentMonthPayMoney);
						//bill.setAgent_fee(currentMonthMinFee);
						//bill.setAgent_balance(currentMonthMinFee);
						//================================================
						Long bill_id=sequenceService.getSequence("bill_id");
						bill.setBill_id(bill_id);
						bill.setCust_id(cust_id);
						bill.setAcct_id(acct_id);
						//bill.setProject_id(project_id);
						//bill.setContract_inst_id(contract_inst_id);
						//bill.setNode_id(node_id);
						bill.setCycle_id(bill_cycle_id);
						//bill.setItem_code(100000);
						bill.setLate_fee(0l);
						bill.setLate_balance(0l);
						//bill.setLatecal_time();
						bill.setBill_pay_tag("0");
						//bill.setAgent_bill_pay_tag("0");
						bill.setUpdate_time(new Date());
						bill.setUpdate_user_id(1l);
						bill.setRsrv_fee1(0l);
						bill.setRsrv_info1("");
						bill.setRemark("");
						billMapper.insertBill(bill);
					}
				}
			}
			logger.info("cust_id="+cust_id+" 账单生成结束");
		}
		if("".equals(custIDs)){
			BsCycle billCycle = new BsCycle();
			billCycle.setCycle_id(bill_cycle_id);
			billCycle.setAct_tag("1");
			BsCycle curCycle = new BsCycle();
			curCycle.setCycle_id(current_cycle_id);
			curCycle.setUse_tag("1");
			bsCycleMapper.updateCycleActTag(billCycle);
			bsCycleMapper.updateCycleUseTag(curCycle);
		}
		//JSONArray results=JSON.parseArray(JSON.toJSONString(bsCusts));
		//System.out.println(results);
		return json;
	}
}
